#include "fxcc/core/Dir.h"
#include "gli/gli.hpp"

using namespace fxcc;

Dir::Dir(const std::string dir)
	:File(dir ,true)
{
	if (Exist())
	{
		Load();
	}
}

void Dir::Load()
{

	m_Dirs.clear();
	m_Files.clear();

	for (const auto it : fs::directory_iterator(m_RelativePath))
	{
		fs::path _p = it.path();
		std::string _pstr = _p.string();

		if (fs::is_directory(_p))
		{
			auto inst = std::make_shared<Dir>(_pstr);
			inst->m_Parent = this;
			m_Dirs.push_back(inst);
		}
		else
		{
			auto inst = std::make_shared<File>(_pstr, false);
			inst->m_Parent = this;
			m_Files.push_back(inst);
		}
	}


}

File::File(const std::string p, bool isDir) :m_IsDir(isDir)
{
	LoadRelativePath(p);
}

std::string fxcc::File::GetFileWithoutRepeat(const std::string& originName, const std::string& suffix)
{
	fs::path _p = fs::path(m_RelativePath) / (originName + suffix);
	
	int index = 1;

	while (fs::exists(_p))
	{
		_p = fs::path(m_RelativePath) / (originName + std::to_string(index) + suffix);
		index++;
	}
	return _p.string();
}

void File::LoadRelativePath(const std::string& p)
{
	if (!fs::exists(p))
	{
		ztclog::info("failed find the path  %s", p.c_str());
		return;
	}
	m_RelativePath = fxcc::Base::normalizePath(p);
	if (m_RelativePath.empty())
	{
		m_RelativePath = p;
	}
	auto _p = fs::absolute(p);
	m_AbsolutePath = _p.string();
	m_FileName = _p.filename().string();
	m_OriginName = fxcc::FileUtil::GetNoSuffixName(m_FileName);
	m_Suffix = GetSuffix(m_FileName);
	m_IsDir = fs::is_directory(p);

	if (m_IsDir)
	{
		m_FileType = fxcc::FileType::_Dir_;
	}
	else
	{
		m_FileType = fxcc::FileUtil::GetFileType(m_Suffix, m_RelativePath);
	};

};

std::string fxcc::FileUtil::GetFileNameWithoutRepeat(const std::string& dir, const std::string& originName, const std::string& suffix)
{
	fs::path _p = fs::path(dir) / (originName + suffix);
	std::string realName = originName;
	int index = 1;

	while (fs::exists(_p))
	{
		_p = fs::path(dir) / realName;
		realName = (originName + std::to_string(index) + suffix);
		index++;
	}
	return realName;
}

std::string fxcc::FileUtil::GetFileWithoutRepeat(const std::string& dir,const std::string& originName, const std::string& suffix)
{
	fs::path _p = fs::path(dir) / (originName + suffix);

	int index = 1;

	while (fs::exists(_p))
	{
		_p = fs::path(dir) / (originName + std::to_string(index) + suffix);
		index++;
	}
	return _p.string();
}

FileType fxcc::FileUtil::GetFileType(const std::string& suffix, const std::string& relativePath)
{
	if (IsOgg(suffix)) return fxcc::FileType::_Ogg_;
	if (IsWav(suffix)) return fxcc::FileType::_Wav_;
	if (IsWICImage(suffix)) return fxcc::FileType::_WIC_;
	if (IsHDRImage(suffix))return fxcc::FileType::_HDR_;
	if (IsDDSImage(suffix)){return fxcc::FileType::_DDS_;}
	if (IsModel(suffix)) return fxcc::FileType::_Model_;
	if (IsACTOR(suffix)) return fxcc::FileType::_Actor_;
	if (IsFontFile(suffix)) return fxcc::FileType::_ttf_ttc_;
	if (isSkinnedFile(suffix)) return fxcc::FileType::_Skinned_;
	if (IsMeshFile(suffix)) return fxcc::FileType::_Mesh_;
	if (IsAnimtionFile(suffix)) return fxcc::FileType::_Anim_;
	if (IsBoneFile(suffix)) return fxcc::FileType::_Bone_;
	if (IsMatFile(suffix)) return fxcc::FileType::_Mat_;
	if (IsRealMaterial (suffix)) return fxcc::FileType::_RealMat_;
	if (IsRealMaterial(suffix)) return fxcc::FileType::_RealMat_;
	if (IsMp3File(suffix)) return fxcc::FileType::_MP3_;
	if (IsCSFile(suffix)) return fxcc::FileType::_CS_;
	if (IsDllFile(suffix)) return fxcc::FileType::_DLL_;
	if (IsPrefeb(suffix)) return fxcc::FileType::_Prefeb_;
	if (IsFrag(suffix)) return fxcc::FileType::_Frag_;
	if (IsGeomertyShader(suffix)) return fxcc::FileType::_Geo_Glsl_;
	if (IsComputeShader(suffix)) return fxcc::FileType::_Compute_Glsl_;
	if (IsEffects(suffix)) return fxcc::FileType::_Effects_;

	return fxcc::FileType::_File_;
}